#include <stdio.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <strings.h>

// 要求：发送进程接受用户提供的文件名字，将文件中的内容复制，通过共享内存接受进程，接受进程读取内容，并存储到参数提供的文件中。
// 提示：send.c和receive.c编译后按如下格式运行
// gcc send.c –o send
// gcc receive.c –o receive
// ./send a(a为存在的有内容的文件)
// ./receive b（b若不存在创建，复制时，若原来有内容，则覆盖）

int main(int argc, char *argv[])
{
	key_t key, key1;
	int id, semid;
	char *ptr;
	struct sembuf sops[6];
	key = ftok("/home/ff/code/linux/test_24_11_11", 'a');
	key1 = ftok("/", 'b');
	semid = semget(key1, 3, IPC_CREAT | 0666);
	id = shmget(key, 1024, IPC_CREAT | 0666);
	ptr = shmat(id, NULL, 0);

	sops[0].sem_num = 0;
	sops[0].sem_op = -1;
	sops[0].sem_flg = SEM_UNDO;
	// P(space)
	sops[1].sem_num = 1;
	sops[1].sem_op = -1;
	sops[1].sem_flg = SEM_UNDO;
	// P(lock)
	sops[2].sem_num = 2;
	sops[2].sem_op = -1;
	sops[2].sem_flg = SEM_UNDO;
	// V(pronum)
	sops[3].sem_num = 0;
	sops[3].sem_op = 1;
	sops[3].sem_flg = SEM_UNDO;
	// V(space)
	sops[4].sem_num = 1;
	sops[4].sem_op = 1;
	sops[4].sem_flg = SEM_UNDO;
	// V(lock)
	sops[5].sem_num = 2;
	sops[5].sem_op = 1;
	sops[5].sem_flg = SEM_UNDO;

	int fd = open(argv[1], O_WRONLY | O_CREAT, 0666);
	while (1)
	{
		// P(pronum);
		semop(semid, &sops[0], 1);
		// P(lock);
		semop(semid, &sops[2], 1);

		if (strcmp(ptr, "end") == 0)
		{
			break;
		}
		printf("共享内存内容字符数：%ld\n", strlen(ptr));
		write(fd, ptr, strlen(ptr));

		sleep(1);
		// V(lock);
		semop(semid, &sops[5], 1);
		// V(space);
		semop(semid, &sops[4], 1);
	}
	close(fd);
	shmdt(ptr);
	printf("文件接收完毕\n");
	semctl(semid, 0, IPC_RMID);
}